package twi.query.template2;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import javax.swing.SwingUtilities;

import twi.Utils;
import twi.filter.DropAnonFilter;
import twi.query.SparqlQuery;
import twi.query.template.NameFactory;
import twi_project.TWI;

import com.hp.hpl.jena.rdf.model.RDFNode;
import com.hp.hpl.jena.vocabulary.RDF;

public class Template implements Serializable{

	ArrayList<TemplateNode> templateNodes = new ArrayList<TemplateNode>();
	private transient TemplateMainView2 view;
	private String name;
	private String description;
	private boolean allMinimized = false;
	
	public Template(TemplateMainView2 templateMainView2) {
		this.view = templateMainView2;
	}


	public void createRootNode() {
		 List l = TWI.getInstance().getOntologieModel().listClasses().filterDrop(new DropAnonFilter()).toList();
		ArrayList<String> classnames = new ArrayList<String>();
		for (int i = 0; i < l.size(); i++){
			RDFNode n = (RDFNode) l.get(i);
	    	String name = Utils.getLocalName(n);
			classnames.add(name);
		}
		TemplateClassNode tcn = new TemplateClassNode(null,this, classnames, null);
		this.templateNodes.add(tcn);
		view.updateAll(templateNodes);
		doLayout();
	}
	public void doLayout(){
		SwingUtilities.invokeLater(new Runnable(){
			public void run(){
				view.getTreePanel().layoutTree();
				view.validate();
			}
		});
	}

	public void doLayout(TemplateNode tcn) {
		for (int i = 0; i < templateNodes.size(); i++)
			templateNodes.get(i).rekursiveMinimize();
		tcn.maximize();
		doLayout();
	}

	public void setName(String name) {
		this.name = name;
	}

	public void setDescription(String desc) {
		this.description = desc;
		
	}

	public String getTemplateDescription() {
		return this.description;
	}

	public String getTemplateName() {
		return this.name;
	}

	public void setMainView(TemplateMainView2 templateMainView2) {
		this.view = templateMainView2;
		for (int i = 0;i < this.templateNodes.size(); i++){
			this.view.getTreePanel().add(this.templateNodes.get(i));
			this.templateNodes.get(i).init(null, false);
			this.templateNodes.get(i).rekursiveMinimize();
		}
	}

	public void minimize() {
		for (int i = 0; i <this.templateNodes.size(); i++)
			this.templateNodes.get(i).rekursiveMinimize();
	}


	public SparqlQuery createSparqlQuery() {
		ArrayList<String> parts = new ArrayList<String>();
		ArrayList<String> varList = new ArrayList<String>();
		for (int i =  0; i < this.templateNodes.size(); i++){
			parts.add(sparqlQuery_rek(this.templateNodes.get(i), null, varList, null));
		}
		String q = "SELECT DISTINCT ";
		for (int i = 0; i < varList.size(); i++)
			q += "?"+varList.get(i)+" ";
		q += "\nWHERE { \n" ;
		for (int i = 0; i< parts.size(); i++)
			q+=parts.get(i)+" \n";
		q+="}";
		SparqlQuery sq = new SparqlQuery(q, TWI.getInstance().getOntologieModel(), true);
		return sq;
	}


	static String baseUri = TWI.getInstance().getOntologieModel().getBasePrefix();
	private String sparqlQuery_rek(TemplateNode node, String parVar, ArrayList<String> varList, String prefProp) {
		String varName = node.getVariableName();
		ArrayList<String> propertyList = node.getVisiblePropertys();
		ArrayList<TemplateNode> individuList = node.getIndividualList();
		String p1 = "?"+varName + " "+RDF.type.getURI() + " "+baseUri+node.getOntClassName()+".\n";
		boolean optional = node.isOptional();
		boolean showVariable = node.showVariable();
		if (optional)
			p1 += "OPTIONAL {\n";
		if (showVariable)
			if (!varList.contains(varName))
				varList.add(varName);
		if (parVar != null)
			p1 += "?"+parVar + " "+baseUri + prefProp + " ?"+varName+".\n";
		if (prefProp != null){
			for (int i = 0; i < individuList.size(); i++){
				TemplateNode indi = individuList.get(i);
				String indiVarName = indi.getVariableName();
				String indiName = indi.getOntClassName();
				if (!indi.showVariable()){
					p1 += "?"+parVar + " "+baseUri+prefProp + " "+baseUri+indiName+".\n";
				}else{
					p1 += "?"+parVar + " " + baseUri + prefProp + " "+baseUri + indiName+ ".\n";
//					p1 += "?"+varName + " "+baseUri + prefProp + " ?"+indiVarName+".\n";
				}
			}
		}
		for (int i = 0; i < propertyList.size(); i++){
			String prop = propertyList.get(i);
			ArrayList<TemplateNode> li = node.getChild(prop);
			for (int j = 0; j < li.size(); j++){
//				TemplateNode child = node.getChild(prop);
				TemplateNode child = li.get(j);
				if (child == null)
					continue;
				PropertyNode pn = node.getPropertyNode(prop);
				if (!pn.datatypeProperty)
					p1 += sparqlQuery_rek(child, varName, varList, prop);
				else{
					String value = node.getPropertyValue(prop);
					String tmp = NameFactory.createNameFromClassName(prop);
					p1 += "?"+varName + " "+baseUri+prop+" ?"+tmp+".\n";
					p1 += "?"+varName + " "+baseUri+prop+" \""+value+"\".\n";
				}
			}
		}
		if (optional)
			p1 += "}\n";
		return p1;
	}


	public void maximize(TemplateNode templateClassNode) {
		this.minimize();
		if (!this.allMinimized)
			templateClassNode.maximize();
	}


	public void setAllMinimized(boolean b) {
		this.allMinimized  = b;
		
	}
	
	
	/*
SELECT ?Student2 ?Modul 
WHERE { 
?Student2 rdf:type :Student.
?Student2 :hatModule ?Modul.
?Student2 :hatModule :Technologien_des_Wissensmanagements_im_Internet.
?Modul rdf:type :Modul.
?Modul rdf:type ?Technologien_des_Wissensmanagements_im_Internet0.
 
}

	 
	}
	 */
}
